package com.lefevre.cms.service.membershipCard.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lefevre.cms.bean.QueryResult;
import com.lefevre.cms.bean.membershipCard.MembershipCard;
import com.lefevre.cms.bean.membershipCard.MembershipCardOrder;
import com.lefevre.cms.bean.membershipCard.Specification;
import com.lefevre.cms.bean.user.UserRoleGroup;
import com.lefevre.cms.mapper.MembershipCardMapper;
import com.lefevre.cms.mapper.MembershipCardOrderMapper;
import com.lefevre.cms.mapper.SpecificationMapper;
import com.lefevre.cms.service.besa.DaoSupport;
import com.lefevre.cms.service.membershipCard.MembershipCardService;
import com.lefevre.cms.service.user.UserRoleService;
import com.lefevre.cms.service.user.UserService;
import com.lefevre.cms.web.action.SystemException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.Query;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 会员卡实现
 *
 * @author Lefevre
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class MembershipCardServiceImpl extends DaoSupport<MembershipCard> implements MembershipCardService {

    @Resource
    UserRoleService userRoleService;
    @Resource
    UserService userService;
    @Resource
    private MembershipCardMapper baseMapper;
    @Resource
    private MembershipCardOrderMapper membershipCardOrderMapper;
    @Resource
    private SpecificationMapper specificationMapper;

    /**
     * 根据Id查询会员卡
     *
     * @param membershipCardId 会员卡Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public MembershipCard findById(Long membershipCardId) {
        return baseMapper.selectById(membershipCardId);
    }

    /**
     * 根据会员卡Id查询规格
     *
     * @param membershipCardId 会员卡Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<Specification> findSpecificationByMembershipCardId(Long membershipCardId) {
        return specificationMapper.selectList(new LambdaQueryWrapper<Specification>()
                .eq(Specification::getMembershipCardId, membershipCardId)
                .orderByAsc(Specification::getSort));
    }

    /**
     * 根据规格Id查询规格
     *
     * @param specificationId 规格Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Specification findSpecificationBySpecificationId(Long specificationId) {
        return specificationMapper.selectById(specificationId);
    }

    /**
     * 查询所有会员卡
     *
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<MembershipCard> findAllMembershipCard() {
        return baseMapper.selectList(new LambdaQueryWrapper<MembershipCard>().orderByDesc(MembershipCard::getSort));
    }

    /**
     * 保存会员卡
     *
     * @param membershipCard 会员卡
     */
    public void saveMembershipCard(MembershipCard membershipCard) {
        baseMapper.insert(membershipCard);

        if (membershipCard.getSpecificationList() != null && membershipCard.getSpecificationList().size() > 0) {
            for (Specification specification : membershipCard.getSpecificationList()) {
                specification.setMembershipCardId(membershipCard.getId());
                specificationMapper.insert(specification);
            }
        }
    }


    /**
     * 修改会员卡
     *
     * @param membershipCard             会员卡
     * @param add_specificationList      添加规格集合
     * @param update_specificationList   修改规格集合
     * @param delete_specificationIdList 删除规格Id集合
     * @return
     */
    public Integer updateMembershipCard(MembershipCard membershipCard, List<Specification> add_specificationList,
                                        List<Specification> update_specificationList, List<Long> delete_specificationIdList) {

        int i = baseMapper.updateById(membershipCard);
        if (i > 0) {
            //删除规格
            if (delete_specificationIdList != null && delete_specificationIdList.size() > 0) {
                this.deleteSpecificationBySpecificationIdList(delete_specificationIdList);
            }
            //修改规格
            if (update_specificationList != null && update_specificationList.size() > 0) {
                for (Specification specification : update_specificationList) {
                    String stock_sql = "";
                    String inventory_where_sql = "";
                    if (specification.getStockStatus().equals(0)) {//不变
                        stock_sql = "o.stock=o.stock+?3,";
                    } else if (specification.getStockStatus().equals(1)) {//增加
                        stock_sql = "o.stock=o.stock+?3,";
                    } else if (specification.getStockStatus().equals(2)) {//减少
                        stock_sql = "o.stock=o.stock-?3,";
                        inventory_where_sql = " and o.stock>=?12";
                    }
                    if (specification.getChangeStock() == null) {
                        specification.setChangeStock(0L);
                    }
                    Query query_style = em.createQuery("update Specification o set o.specificationName=?1,o.membershipCardId=?2," +
                                    stock_sql + "o.point=?4, o.marketPrice=?5, o.sellingPrice=?6, o.enable=?7,o.sort=?8,o.duration=?9,o.unit=?10 where o.id=?11" + inventory_where_sql)
                            .setParameter(1, specification.getSpecificationName())//规格名称
                            .setParameter(2, specification.getMembershipCardId())//会员卡Id
                            .setParameter(3, specification.getChangeStock())//更改库存量
                            .setParameter(4, specification.getPoint())//积分
                            .setParameter(5, specification.getMarketPrice())//市场价
                            .setParameter(6, specification.getSellingPrice())//销售价

                            .setParameter(7, specification.isEnable())//是否启用
                            .setParameter(8, specification.getSort())//排序
                            .setParameter(9, specification.getDuration())//时长
                            .setParameter(10, specification.getUnit())//时长单位
                            .setParameter(11, specification.getId());
                    if (!"".equals(inventory_where_sql)) {
                        query_style.setParameter(12, specification.getChangeStock());
                    }
                    int p = query_style.executeUpdate();
                }
            }
            //添加规格
            if (add_specificationList != null && add_specificationList.size() > 0) {
                for (Specification specification : add_specificationList) {
                    this.save(specification);
                }
            }
        }
        return i;
    }

    /**
     * 删除会员卡
     *
     * @param membershipCardId 会员卡Id
     */
    public Integer deleteMembershipCard(Long membershipCardId) {
        int i = baseMapper.deleteById(membershipCardId);
        if (i > 0) {
            i += specificationMapper.delete(new LambdaUpdateWrapper<Specification>().eq(Specification::getMembershipCardId, membershipCardId));
        }
        return i;
    }


    /**
     * 根据规格Id删除规格
     *
     * @param specificationIdList 会员卡Id集合
     */
    private Integer deleteSpecificationBySpecificationIdList(List<Long> specificationIdList) {
        return specificationMapper.deleteBatchIds(specificationIdList);
    }


    /**----------------------------------------------------- 会员卡订单 -----------------------------------------------------**/

    /**
     * 根据用户名称查询会员卡订单分页
     *
     * @param userName   用户名称
     * @param firstIndex 索引开始,即从哪条记录开始
     * @param maxResult  获取多少条数据
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public QueryResult<MembershipCardOrder> findMembershipCardOrderByUserName(String userName, int firstIndex, int maxResult) {
        QueryResult<MembershipCardOrder> qr = new QueryResult<>();

        LambdaQueryWrapper<MembershipCardOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MembershipCardOrder::getUserName, userName);
        wrapper.orderByDesc(MembershipCardOrder::getCreateDate);
        Page<MembershipCardOrder> membershipCardOrderPage = membershipCardOrderMapper.selectPage(new Page<>(firstIndex, maxResult), wrapper);

        qr.setResultlist(membershipCardOrderPage.getRecords());
        qr.setTotalrecord(membershipCardOrderPage.getTotal());

        return qr;
    }

    /**
     * 保存会员卡订单
     *
     * @param membershipCardOrder  会员卡订单
     * @param add_userRoleGroup    增加用户角色组
     * @param update_userRoleGroup 修改用户角色组
     * @param pointLog             积分支付日志
     * @param paymentLog           预存款支付日志
     */
    public void saveMembershipCardOrder(MembershipCardOrder membershipCardOrder, UserRoleGroup add_userRoleGroup, UserRoleGroup update_userRoleGroup,
                                        Object pointLog, Object paymentLog) {
        membershipCardOrderMapper.insert(membershipCardOrder);

        //角色组不存在时添加
        if (add_userRoleGroup != null) {
            List<UserRoleGroup> userRoleGroupList = new ArrayList<>();
            userRoleGroupList.add(add_userRoleGroup);
            userRoleService.saveUserRoleGroup(userRoleGroupList);
        }
        //角色组存在时更新
        if (update_userRoleGroup != null) {
            int i = userRoleService.updateUserRoleGroup(update_userRoleGroup.getUserRoleId(), update_userRoleGroup.getUserName(), update_userRoleGroup.getValidPeriodEnd());
            if (i == 0) {
                throw new SystemException("角色组更新错误");
            }
        }
        //扣除用户金额
        if (membershipCardOrder.getPaymentAmount().compareTo(new BigDecimal("0")) > 0) {
            int i = userService.subtractUserDeposit(membershipCardOrder.getUserName(), membershipCardOrder.getPaymentAmount(), paymentLog);
            if (i == 0) {
                throw new SystemException("扣除用户金额错误");
            }
        }
        //扣除用户积分
        if (membershipCardOrder.getPaymentPoint() > 0L) {
            int i = userService.subtractUserPoint(membershipCardOrder.getUserName(), membershipCardOrder.getPaymentPoint(), pointLog);
            if (i == 0) {
                throw new SystemException("扣除用户金额错误");
            }
        }
        //扣减库存
        int j = this.reduceSpecificationStock(Long.parseLong("" + membershipCardOrder.getQuantity()), membershipCardOrder.getSpecificationId());
        if (j == 0) {
            throw new SystemException("扣减库存错误");

        }
    }

    /**
     * 减少会员卡库存,增加占用库存
     *
     * @param stock           库存量
     * @param specificationId 规格Id
     * @return
     */
    private Integer reduceSpecificationStock(Long stock, Long specificationId) {
        Specification specification = specificationMapper.selectOne(new LambdaQueryWrapper<Specification>().eq(Specification::getMembershipCardId, specificationId)
                .ge(Specification::getStock, stock)
                .gt(Specification::getStock, 0));
        specification.setStock(specification.getStock() - stock);
        specification.setStockOccupy(specification.getStockOccupy() + stock);

        return specificationMapper.updateById(specification);
    }

}
